package org.mipt.infsec.steganography.impl.petzib;

import org.mipt.infsec.steganography.api.ImageDecryptor;
import org.mipt.infsec.steganography.api.datastorage.Bit;
import org.mipt.infsec.steganography.impl.petzib.keys.KeyGeneratorImpl;
import org.mipt.infsec.steganography.impl.petzib.keys.KeyImpl;
import org.mipt.infsec.steganography.utils.ConvertUtils;

import java.io.File;
import java.io.IOException;

public class DecryptorImpl extends ImageDecryptor
{
    /**
     * Extension of in picture
     */
    private String extension;

    public DecryptorImpl()
    {
    }

    public DecryptorImpl(File file, String data) throws IOException
    {
        super(file, data);
    }

    @Override
    public Object decrypt()
    {
        KeyImpl[] keys = ((KeyGeneratorImpl)KeyGeneratorImpl.getInstance()).seek(getData());

        Bit[] bits = new Bit[keys.length];
        System.out.println("Keys " + keys.length);
        for (int i = 0; i < Math.min(getImage().getWidth(), keys.length); i++)
        {
            int q = keys[i].getValue();
            int result = 0;
            for (int j = q; j < getImage().getHeight(); j += q)
            {
                 Bit bit = getBitFromPixel(i,j);
                 if (bit.isUNIT()) result++;
                 else result--;
            }
            if (result > 0) bits[i] = new Bit(true);
            else bits[i] = new Bit(false);
        }

        try{
            return ConvertUtils.bitsToString(bits);
        }catch (Exception e)
        {
            e.printStackTrace();
        }
        return "";
    }

    /**
     *
     * @param x
     * @param y
     * @return
     */
    private Bit getBitFromPixel(int x, int y)
    {
        int number = 0;
        int blue_amount = 0;
        for (int i = x - 2; i < x + 2; i++)
            for (int j = y - 2; j < y + 2; j++)
                if (Math.abs(i - x) + Math.abs(j - y) <= 2)
                {
                     if ((i >= 0) && (i < getImage().getWidth()) &&
                             (j >= 0) &&(j < getImage().getHeight()) &&
                             ((i != x) && (j != y)))
                     {
                         number++;
                         blue_amount += getImage().getPixel(i,j)[2];
                     }

                }

        int average_blue = blue_amount / number;
        int  blue = getImage().getPixel(x,y)[2];
        if (blue > average_blue) return new Bit(true);
        else return new Bit(false);
    }
}
